package com.wzy.scns.controller;

import com.wzy.scns.entity.SelectCourse;
import com.wzy.scns.repositery.CourseRepository;
import com.wzy.scns.repositery.SelectCourseRepository;
import com.wzy.scns.vo.SCStuInfo;
import com.wzy.scns.vo.StudentSelectMsgVo;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;
import java.time.LocalDate;
import java.util.*;


@Validated
@RestController
@RequestMapping("/selectCourse")
@RestControllerAdvice
public class SelectCourseController {

    @Autowired
    SelectCourseRepository selectCourseRepository;
    @Autowired
    CourseRepository courseRepository;

    @PostMapping("/add")
    public Map add(@NotNull String studentCode, @NotNull String courseCode) {
        if (courseRepository.findByCode(courseCode) == null)
            return errorMap("课程不存在");
        if (selectCourseRepository.findByStudentCodeAndCourseCode(studentCode, courseCode) != null)
            return errorMap("请不要重复选该课");

        SelectCourse sc = new SelectCourse();
        sc.setSelectDate(LocalDate.now());
        sc.setCourseCode(courseCode);
        sc.setStudentCode(studentCode);
        sc.setAchievement((float) 0);//选课后成绩为0
        List<SelectCourse> scs = new ArrayList();
        scs.add(selectCourseRepository.save(sc));
        return postMap("选课成功", 1);
    }

    @PostMapping("/quit")
    public Map quit(String studentCode, String courseCode) {
        if (selectCourseRepository.findByStudentCodeAndCourseCode(studentCode, courseCode) == null)
            return errorMap("您未报名该课程");
        if (selectCourseRepository.removeByCourseCodeAndStudentCode(courseCode, studentCode) > 0)
            return postMap("退课成功", 1);
        else
            return errorMap("退课失败");
    }

    /*
     * 未测试
     */
    @PostMapping("/deleteByStudentCode")
    public Map deleteByStudentCode(@NotNull String studentCode) {
        Integer total = selectCourseRepository.deleteByStudentCode(studentCode);
        return postMap("删除成功", total);
    }

    //教师评定学生成绩，需要教师工号，验证该门课程是否由该老师教授
    @PostMapping("/updateAchievement")
    public Map updateAchievement(@NotNull String studentCode, @NotNull String courseCode, @NotNull float a) {
        SelectCourse sc = selectCourseRepository.findByStudentCodeAndCourseCode(studentCode, courseCode);
        sc.setAchievement(a);
        selectCourseRepository.save(sc);
        return postMap("修改成功", 1);
    }

    /*
     * 查询
     * */
    //jpql
//实现根据学号查询学生所选课程的接口
// （查询出的数据需要包含学号，姓名，课程编号，课程名，成绩），按成绩升序排序输出。
    @GetMapping("/getMsgBySCode")
    public Page<StudentSelectMsgVo> getMsgBySCode(@NotNull String studentCode, @RequestParam(defaultValue = "0") Integer currentPage,
                                                  @RequestParam(defaultValue = "5") Integer pageSize) {
        Pageable pageable = PageRequest.of(currentPage, pageSize, Sort.Direction.ASC, "achievement");
        Page<StudentSelectMsgVo> msgs = selectCourseRepository.selectMsgBySCodeOrder(studentCode, pageable);
        return msgs;
    }

    //jpql
//实现根据学号，统计查询该生所选课程的平均分的接口
    @GetMapping("/getAvg")
    public Map getAvg(@NotNull String studentCode) {
        List<SelectCourse> msgs = selectCourseRepository.findByStudentCode(studentCode);
        Float[] arr = new Float[msgs.size()];
        if (arr.length == 0)
            return getMap("暂未加入课程", 0);
        for (int i = 0; i < msgs.size(); i++) {
            arr[i] = msgs.get(i).getAchievement();
        }
        return getMap("查询成功", Avg(arr));
    }

    //实现根据课程名称查询选修该课程的学生的接口，
// （查询出的数据需要包含课程编号，课程名称，学生学号，姓名，性别，系部，选课时间，成绩），
// 分页查询并按学生编号升序排序输出。
    @GetMapping("/getSCStuInfo")
    public Page<SCStuInfo> getSCStuInfo(@NotNull String courseCode, @RequestParam(defaultValue = "0") Integer currentPage,
                                        @RequestParam(defaultValue = "5") Integer pageSize) {
        Pageable pageable = PageRequest.of(currentPage, pageSize, Sort.Direction.ASC, "code");
        Page<SCStuInfo> msgs = selectCourseRepository.getSCStuInfo(courseCode, pageable);
        return msgs;
    }

    //实现根据课程名称，统计查询课程的最高分、最低分、平均分的接口
    @GetMapping("/getCourseMsgByCCode")
    public Map getCourseMsgByCCode(@NotNull String courseCode) {
        Float[] arr = selectCourseRepository.getMaxMinAvgByCCode(courseCode);
        if (arr.length == 0) {
            Map map = new HashMap();
            map.put("max", 0);
            map.put("min", 0);
            map.put("avg", 0);
            return getMap("查询成功", map);
        }
        Arrays.sort(arr);
        Map<String, Float> map = new HashMap();
        map.put("max", arr[arr.length - 1]);
        map.put("min", arr[0]);
        map.put("avg", Avg(arr));
        return getMap("查询成功", map);
    }
    @GetMapping("/getCourseAchievement")
    public Map getCourseAchievement(@NotNull String courseCode) {
        Map map = selectCourseRepository.findMaxMinAvg(courseCode);
        return getMap("查询成功", map);
    }

    public Float Avg(Float[] arr) {
        float sum = 0;
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
        }
        return sum / arr.length;
    }

    public Map getMapTotal(String msg, List data, Object total) {
        Map map = new HashMap();
        map.put("data", data);
        map.put("msg", msg);
        map.put("code", 1);
        map.put("total", total);

        return map;
    }

    public Map getMap(String msg, Object data) {
        Map map = new HashMap();
        map.put("data", data);
        map.put("msg", msg);
        map.put("code", 1);
        return map;
    }

    public Map postMap(String msg, Integer totalSelf) {
        Map map = new HashMap();
        map.put("code", 1);
        map.put("msg", msg);
        map.put("total", totalSelf);
        return map;
    }

    public Map errorMap(String msg) {
        Map map = new HashMap();
        map.put("code", 0);
        map.put("msg", msg);
        return map;
    }

}
